home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / GCC / V2-4-5 / GPPLIBSR00 / cc / procbuf < prev    next >
Text File  |  1993-12-07  |  3KB  |  127 lines

  1. //    This is part of the iostream library, providing input/output for C++.
  2. //    Copyright (C) 1992 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #define _POSIX_SOURCE
  19. #include "ioprivate.h"
  20. #include "procbuf.h"
  21.  
  22. extern "C"
  23.   {
  24.   #include <signal.h>
  25.   #include <unistd.h>
  26.   }
  27.  
  28. //#include <sys/wait.h>
  29.  
  30.  
  31. #ifndef FORK
  32. #define FORK vfork
  33. #endif
  34.  
  35. procbuf::procbuf(const char *command, int mode) : filebuf()
  36. {
  37.     open(command, mode);
  38. }
  39.  
  40. procbuf *procbuf::open(const char *command, int mode)
  41. {
  42.     int read_or_write;
  43.     if (is_open())
  44.     return NULL;
  45.     int pipe_fds[2];
  46.     int parent_end, child_end;
  47.     if (::pipe(pipe_fds) < 0)
  48.     return NULL;
  49.     if (mode == ios::in) {
  50.     parent_end = pipe_fds[0];
  51.     child_end = pipe_fds[1];
  52.     read_or_write = _S_NO_WRITES;
  53.     }
  54.     else {
  55.     parent_end = pipe_fds[1];
  56.     child_end = pipe_fds[0];
  57.     read_or_write = _S_NO_READS;
  58.     }
  59.     _pid = FORK();
  60.     if (_pid == 0) {
  61.     ::close(parent_end);
  62.     int child_std_end = mode == ios::in ? 1 : 0;
  63.     if (child_end != child_std_end) {
  64.         ::dup2(child_end, child_std_end);
  65.         ::close(child_end);
  66.     }
  67.     ::execl("/bin/sh", "sh", "-c", command, NULL);
  68.     ::_exit(127);
  69.     }
  70.     ::close(child_end);
  71.     if (_pid < 0) {
  72.     ::close(parent_end);
  73.     return NULL;
  74.     }
  75.     _fb._fileno = parent_end;
  76.     xsetflags(read_or_write, _S_NO_READS|_S_NO_WRITES);
  77.     return this;
  78. }
  79.  
  80. /* #define USE_SIGMASK */
  81.  
  82. int procbuf::sys_close()
  83. {
  84.     _G_pid_t wait_pid;
  85.     int status = filebuf::sys_close();
  86.     if (status < 0)
  87.     return status;
  88.     int wstatus;
  89. #if defined(SIG_BLOCK) && defined(SIG_SETMASK)
  90.     sigset_t set, oset;
  91.     sigemptyset (&set);
  92.     sigaddset (&set, SIGINT);
  93.     sigaddset (&set, SIGQUIT);
  94.     sigaddset (&set, SIGHUP);
  95.     sigprocmask (SIG_BLOCK, &set, &oset);
  96. #else
  97. #ifdef USE_SIGMASK
  98.     int mask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGHUP));
  99. #else
  100.     typedef void (*void_func)(int);
  101.     void_func intsave = (void_func)signal(SIGINT, SIG_IGN);
  102.     void_func quitsave = (void_func)signal(SIGQUIT, SIG_IGN);
  103.     void_func hupsave = (void_func)signal(SIGHUP, SIG_IGN);
  104. #endif
  105. #endif
  106.     while ((wait_pid = wait(&wstatus)) != _pid && wait_pid != -1) { }
  107. #if defined(SIG_BLOCK) && defined(SIG_SETMASK)
  108.     sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  109. #else
  110. #ifdef USE_SIGMASK
  111.     (void) sigsetmask(mask);
  112. #else
  113.     signal(SIGINT, intsave);
  114.     signal(SIGQUIT, quitsave);
  115.     signal(SIGHUP, hupsave);
  116. #endif
  117. #endif
  118.     if (wait_pid == -1)
  119.     return -1;
  120.     return 0;
  121. }
  122.  
  123. procbuf::~procbuf()
  124. {
  125.     close();
  126. }
  127.